#pragma once
#include <iostream>
#include <cstring>
#include <string>
#include <fcntl.h>
#include <assert.h>
#include <time.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <cstdarg>
using namespace std;

#define FILEMOD 0666
#define BUFFSIZE 1024
char buff[BUFFSIZE];//日志buff
const char* WDAY[] = {"天","一","二","三","四","五","六"};
const char* LEVEL[] = {"info","waring","error","fatol","debug"};

//根据日志等级和用户自定义内容,生成日志字符串到buff
//只生成 日期, 文件, 行信息, 不处理可变参数部分
int BuildBuff(const char* level,const char* file,const int line){
    time_t timep;
    time(&timep);
    struct tm* p = localtime(&timep);
    int len = snprintf(buff,BUFFSIZE,"[%s][%d-%d-%d %d:%d:%d][星期%s] : [flie: \"%s\", line: \"%d\"] : ",
        level,p->tm_year+1900,p->tm_mon+1,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec,WDAY[p->tm_wday],
        file, line);
    return len;
}

//按追加方式打开文件
int OpenFile(const char* filename){
    int fd = open(filename,O_APPEND|O_CREAT|O_WRONLY,FILEMOD);
    if(fd == -1){
        //创建目录
        mkdir("./log",0766);
        fd = open(filename,O_APPEND|O_CREAT|O_WRONLY,FILEMOD);
        assert(fd>=0);
    }
    return fd;
}

//把全局buff内容写入指定文件
void WriteFile(int fd){
    if(write(fd,buff,strlen(buff)) < 0){
        perror("write");
        //exit(errno); //可选
    }
}

//Log接口
//levet : 日志等级
//format : 格式化输入字符串
//... : 可变参数部分
#define Log(level,format,...) log(level, __FILE__, __LINE__, format, ##__VA_ARGS__)
void log(const char* level,const char* file,const int line,const char* format, ...){
    int len = BuildBuff(level,file,line);

    //处理可变参数
    va_list args;
    va_start(args,format);
    len += vsnprintf(buff + len, BUFFSIZE - len, format, args);//格式化输出可变参数
    va_end(args);

    if(len + 1 < BUFFSIZE){
        buff[len] = '\n';
        buff[len+1] = '\0'; 
    }
    
     //打开文件并写入
    int fd = OpenFile("./log/log.txt");
    WriteFile(fd);
    WriteFile(1);
    close(fd);
}
